package com.github.florent37.mylittlecanvas;

import ohos.agp.components.Component;
import ohos.multimodalinput.event.TouchEvent;

public class TouchEventDetector {
    private float mLastTouchX;
    private float mLastTouchY;
    private int mActivePointerId;
    private float mPosX;
    private float mPosY;
    private Listener listener;

    public void setListener(Listener listener) {
        this.listener = listener;
    }

    public void onTouchEvent(TouchEvent event, Component component) {
        final int action = event.getAction();

        switch (action) {
            case TouchEvent.PRIMARY_POINT_DOWN: {
                final float x = getTouchX(event, 0, component);
                final float y = getTouchY(event, 0, component);

                // Remember where we started (for dragging)
                mPosX = x;
                mPosY = y;

                mLastTouchX = x;
                mLastTouchY = y;
                // Save the ID of this pointer (for dragging)
                mActivePointerId = event.getPointerId(0);

                if (listener != null) {
                    listener.onTouched(mPosX, mPosY);
                }

                break;
            }

            case TouchEvent.POINT_MOVE: {
                // Find the index of the active pointer and fetch its position
                final float x = getTouchX(event, 0, component);
                final float y = getTouchY(event, 0, component);

                // Calculate the distance moved
                final float dx = x - mLastTouchX;
                final float dy = y - mLastTouchY;

                mPosX += dx;
                mPosY += dy;

                if (listener != null) {
                    listener.onMoved(dx, dy, mPosX, mPosY);
                }

                // Remember this touch position for the next move event
                mLastTouchX = x;
                mLastTouchY = y;

                break;
            }

            case TouchEvent.PRIMARY_POINT_UP:

            case TouchEvent.CANCEL: {
                if (listener != null) {
                    listener.onRelease(mPosX, mPosY);
                }
                mActivePointerId = -1;
                break;
            }
        }
    }

    public interface Listener {
        void onTouched(float x, float y);

        void onMoved(float differenceX, float differenceY, float newX, float newY);

        void onRelease(float x, float y);
    }

    private float getTouchX(TouchEvent touchEvent, int index, Component component) {
        float touchX = 0;
        if (touchEvent.getPointerCount() > index) {
            int[] xy = component.getLocationOnScreen();
            if (xy != null && xy.length == 2) {
                touchX = touchEvent.getPointerScreenPosition(index).getX() - xy[0];
            } else {
                touchX = touchEvent.getPointerPosition(index).getX();
            }
        }
        return touchX;
    }

    private float getTouchY(TouchEvent touchEvent, int index, Component component) {
        float touchY = 0;
        if (touchEvent.getPointerCount() > index) {
            int[] xy = component.getLocationOnScreen();
            if (xy != null && xy.length == 2) {
                touchY = touchEvent.getPointerScreenPosition(index).getY() - xy[1];
            } else {
                touchY = touchEvent.getPointerPosition(index).getY();
            }
        }
        return touchY;
    }
}
